package com.demo.cms.webapp.template.directive;

import java.io.IOException;
import java.io.Writer;
import java.util.HashMap;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.beans.factory.annotation.Autowired;

import com.demo.cms.service.NaviService;
import com.demo.common.StringUtils;
import com.demo.core.model.support.AdjacencyListModel;
import com.demo.webapp.kcfinder.freemarker.FreemarkerManager;
import com.demo.webapp.views.freemarker.directive.core.PageContextDirectiveSupport;

import freemarker.core.Environment;
import freemarker.core.Environment.TemplateDirectiveBodyEx;
import freemarker.ext.servlet.HttpRequestHashModel;
import freemarker.template.SimpleHash;
import freemarker.template.TemplateException;
import freemarker.template.TemplateModel;
import freemarker.template.TemplateModelException;

/**
 * 菜单的自定义指令
 * <br>
 * 作用:生成菜单
 * @author ryuu.kk
 *
 */
public class MenuDirective extends PageContextDirectiveSupport {

	/**
	 * 页面模板名
	 */
	private static final String MENU_TEMPLATE_NAME = "classpath:/com/demo/cms/webapp/template/menu.ftl";
	
	/**
	 * 栏目服务
	 */
	@Autowired
	private NaviService naviService;
	
	/**
	 * Menu菜单缓存
	 */
	private Map<CacheKey, Object> cacheWrapper;
	
	public MenuDirective() {
		if (cacheWrapper == null) {
			cacheWrapper = new HashMap<CacheKey, Object>();
		}
	}
	@SuppressWarnings("rawtypes")
	@Override
	public void preWriter(Environment env, TemplateDirectiveBodyEx bodyEx,
			TemplateModel[] loopVars, SimpleHash hash, Map params)
			throws IOException, TemplateException {
		
		HttpRequestHashModel requestModel = (HttpRequestHashModel) hash.get(FreemarkerManager.KEY_REQUEST);
		
		// 菜单id
		Long id = null;
		// 取得树的层级
		int level = 3;
		// 使用缓存
		boolean cache = getBoolean("cache", params, true);
		
		String base = "/";
		// 当前url地址
		String url = base;
		HttpServletRequest request = null;
		HttpServletResponse response = null;
		if (requestModel != null) {
			request = requestModel.getRequest();
			response = requestModel.getResponse();
			base = request.getContextPath();
			url = request.getRequestURI();
			if (StringUtils.isNotEmpty(request.getQueryString())) {
				url += "?" + request.getQueryString();
			}
			url = response.encodeURL(url);
		}
		
		
		AdjacencyListModel menu = null;
		id = getLong("id", params);
		level = getInteger("depth", params, level);
		int[] depaths = null;
		if (level > 0) {
			depaths = new int[level + 1];
			for (int i = 0; i <= level; i ++) {
				depaths[i] = i;
			}
		}
		// 只查询可用信息
		menu = naviService.queryTree(null, id, Boolean.TRUE, depaths);
		// 设置menu对象
		hash.put("menu", menu);
		// 当前请求地址
		hash.put("url", url);
	}

	@SuppressWarnings("rawtypes")
	@Override
	public String getTemplatePath(Map params) {
		String path = "";
		try {
			path = getString("path", params, MENU_TEMPLATE_NAME);
		} catch (TemplateModelException e) {}
		return path;
	}
	
	@Override
	public void afterInvoke(Writer writer) {
	}
	
	private class CacheKey {
		private String key;
		private Long siteId;
		private Long menuId;
		private int[] depths;
		public CacheKey(String key, Long siteId, Long menuId, int[] depths) {
			this.key = key;
			this.siteId = siteId;
			this.menuId = menuId;
			this.depths = depths;
		}
		@Override
		public int hashCode() {
			int code = 31;
			code += key.hashCode();
			code ^= (siteId + 1) * 31;
			code ^= (menuId + 1)* 31;
			if (depths != null) {
				for (int depth : depths) {
					code ^= depth;
				}
			} else {
				code ^= 0;
			}
			return code;
		}
	}
}
